August 08, 2021
const a = [1, 'ab"c', true, undefined, null, _ => 3];
JSON.stringify(a);
아래 법칙들을 이용해서 stringify 만들기 (꼬리재귀, 루프 두가지 방법으로)
const stringCheck = [
[/[\r\n\l]/g, '\\n'],
[/"/g, '\\"'],
[/\t/g, '\\t'],
];
const el = {
number: v => v.toString(),
boolean: v => v.toString(),
string: v =>
`"${stringCheck.reduce((acc, cur) => acc.replace(cur[0], cur[1]), v)}"`,
stringify(v) {
return this[typeof v]?.(v) ?? 'null';
},
};
const recursive = (arr, acc, i) => {
return i < arr.length
? recursive(arr, acc + `,${el.stringify(arr[i])}`, i + 1)
: `[${acc.substr(1)}]`;
};
const stringify = arr => {
if (!Array.isArray(arr)) throw 'invalid array';
return arr.length === 0 ? '[]' : recursive(arr, '', 0);
};
stringify([1, 'a', () => {}]);
const stringCheck = [
[/[\r\n\l]/g, '\\n'],
[/"/g, '\\"'],
[/\t/g, '\\t'],
];
const el = {
number: v => v.toString(),
boolean: v => v.toString(),
string: v =>
`"${stringCheck.reduce((acc, cur) => acc.replace(cur[0], cur[1]), v)}"`,
stringify(v) {
return this[typeof v]?.(v) ?? 'null';
},
};
const arrValidator = arr => {
if (!Array.isArray(arr)) throw 'invalid array';
};
let EMPTY = {};
const stringify = arr => {
// validator 코드분리
arrValidator(arr);
let result = EMPTY;
// if는 optional, shield 일 경우 쓴다.
// if else 는 binary mandatory일 경우 쓴다.
if (arr.length === 0) result = '[]';
else {
let acc = '',
i = 0;
while (i < acc.length) {
acc + `,${el.stringify(arr[i])}`;
}
result = `[${acc.substr(1)}]`;
}
// 지금은 코드가 단순하지만 복잡해지면 아래와 같은 가드를 둬야 한다.
// if else는 무조건 둘중하나 거치기 때문에 result가 변하는게 맞다.
if (result === EMPTY) throw 'no processed';
return result;
};
재귀를 루프문으로 번역할 때는 while을 쓰는게 옳다.